package com.techshinogongjian.fp.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.os.Environment;
import android.support.annotation.NonNull;

import com.fingerUsb.OnConnectListener;
import com.siecom.nativelibs.SerialPort;
import com.techshinogongjian.fingerprint.FPConfig;
import com.techshinogongjian.fingerprint.TCFP;
import com.techshinogongjian.fp.client.TcFingerClient;
import com.techshinogongjian.fp.comm.LaserXComm;
import com.techshinogongjian.fp.comm.TwoSerialComm;
import com.techshinogongjian.fp.func.IFingerprintFunc;
import com.techshinogongjian.fp.func.LaserXFuncImpl;
import com.techshinogongjian.fp.func.TwoSerialFuncImpl;

/**
 * 串口工具类
 * 
 * @author wangzhi
 */
public class SerialPortUtil {

	private static final String TAG = SerialPortUtil.class.getSimpleName();

	public enum Protocol {
		LASERX, TWO
	}

	private Protocol mProtocol = Protocol.LASERX;
	private static SerialPortUtil mInstance;
	private Context mContext;
	private SerialPort mSerialPort;
	private InputStream mInputStream;
	private OutputStream mOutputStream;

	private IFingerprintFunc mFingerprintFunc;
	private OnConnectListener mOnConnectListener;

	private TCFP mTcfp;

	private SerialPortUtil(Context context) {
		mContext = context;
	}

	public static SerialPortUtil getInstance(@NonNull Context context) {
		if (mInstance == null) {
			mInstance = new SerialPortUtil(context);
		}
		return mInstance;
	}

	public void setOnConnectListener(OnConnectListener onConnectListener) {
		mOnConnectListener = onConnectListener;
	}

	public TcFingerClient openDevice(String path, int baudrate) {
		try {
			File file = new File(path);
			Logs.i(TAG,
					"canRead:" + file.canRead() + " canWrite:"
							+ file.canWrite() + " exists:" + file.exists());
			mSerialPort = new SerialPort(file, baudrate, 0);
			mInputStream = mSerialPort.getInputStream();
			mOutputStream = mSerialPort.getOutputStream();

			if (mProtocol == Protocol.LASERX) {
				LaserXComm comm = new LaserXComm(mInputStream, mOutputStream);
				mFingerprintFunc = new LaserXFuncImpl(comm);
//				comm.setInitOk(initTCFP());
				comm.setInitOk(true);
			} else if (mProtocol == Protocol.TWO) {
				mFingerprintFunc = new TwoSerialFuncImpl(new TwoSerialComm(
						mInputStream, mOutputStream));
			}

			return new TcFingerClient(mFingerprintFunc, mContext);
		} catch (SecurityException e) {
			e.printStackTrace();
			Logs.e(TAG, e.getMessage());
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			Logs.e(TAG, e.getMessage());
			return null;
		}
	}

	/**
	 * 初始化算法
	 */
	private boolean initTCFP() {
		String path = Environment.getExternalStorageDirectory().getPath()
				+ "/TcFingerprintTemp";
		File file = new File(path);
		if (!file.exists() && !file.isFile()) {
			file.mkdir();
		}
		FPConfig.setFeatureType(FPConfig.FEATURE_TYPE_BASE64);
		// 初始化指纹算法
		mTcfp = new TCFP(mContext);
		int code = mTcfp.TCFP_Init(0, 0, "");
		return code == 1;
	}

	public void closeDevice() {
		if (mTcfp != null) {
			mTcfp.TCFP_UnInit();
		}
		if (mSerialPort != null) {
			mSerialPort.close();
			mSerialPort = null;
		}
	}

	public void setProtocol(Protocol protocol) {
		mProtocol = protocol;
	}

	public int write(byte[] data) {
		try {
			mOutputStream.write(data);
		} catch (IOException e) {
			e.printStackTrace();
			return -1;
		}
		return 0;
	}

	public int read(byte[] data, int off, int length) {
		int ret = -1;
		try {
			ret = mInputStream.read(data, off, length);
		} catch (IOException e) {
			e.printStackTrace();
			return ret;
		}
		return ret;
	}

	public int avalible() {
		int ret = -1;
		try {
			ret = mInputStream.available();
		} catch (IOException e) {
			e.printStackTrace();
			return ret;
		}
		return ret;
	}
}
